
import { MapType,MapState,RoadState } from "./map/base/MapType";
import MapLayer from "./map/layer/MapLayer";
import EntityLayer from "./map/layer/EntityLayer";
import Charactor from "./map/charactor/Charactor";
import RoadNode from "./map/road/RoadNode";
import IRoadSeeker from "./map/road/IRoadSeeker";
import MapData from "./map/base/MapData";
import MapRoadUtils from "./map/road/MapRoadUtils";
import RoadDrawManager from "./editor/RoadDrawManager";
import AstarHoneycombRoadSeeker from "./map/road/AstarHoneycombRoadSeeker";
import AStarRoadSeeker from "./map/road/AStarRoadSeeker";
import Point from "./map/road/Point";

// Learn TypeScript:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/typescript.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/reference/attributes.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/life-cycle-callbacks.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

@ccclass
export default class SceneMap extends cc.Component {

    @property(cc.Node)
    public layer: cc.Node = null;

    @property(MapLayer)
    public mapLayer: MapLayer = null;

    @property(EntityLayer)
    public entityLayer: EntityLayer = null;

    @property(Charactor)
    private player:Charactor = null;

    @property(cc.Camera)
    private camera:cc.Camera = null;

    @property()
    public isFollowPlayer:boolean = true;

    @property(RoadDrawManager)
    public roadDrawManager:RoadDrawManager = null;
    @property(cc.Node)
    newDialogNode:cc.Node = null;

    @property(cc.Node)
    openDialogNode:cc.Node = null;

    private _roadDic:{[key:string]:RoadNode} = {};

    private _roadSeeker:IRoadSeeker;

    private targetPos:cc.Vec2 = cc.Vec2.ZERO;

    private _mapData:MapData = null;
    private _mapState:MapState = MapState.stay; //根据状态设置地图
    private _isRightMouse:boolean = false;
    // LIFE-CYCLE CALLBACKS:

    // onLoad () {}

    start () {

        this.node.x = -cc.winSize.width / 2;
        this.node.y = -cc.winSize.height / 2;

        this.player.sceneMap = this;
        this.node.on(cc.Node.EventType.MOUSE_DOWN,this.onMapMouseDown,this);
        this.node.on(cc.Node.EventType.MOUSE_UP,this.onMapMouseEnd,this);
        this.node.on(cc.Node.EventType.MOUSE_LEAVE,this.onMapMouseEnd,this);
        this.node.on(cc.Node.EventType.MOUSE_MOVE,this.onMouseMove,this);

    }

    public init(mapData:MapData,bgTex:cc.Texture2D)
    {
 
        this._mapData = mapData;

        MapRoadUtils.instance.updateMapInfo(mapData.mapWidth,mapData.mapHeight,mapData.nodeWidth,mapData.nodeHeight,mapData.type);

        this.mapLayer.init(mapData.mapWidth,mapData.mapHeight,256,256,bgTex);
    
        var len:number = mapData.roadDataArr.length;
        var len2:number = mapData.roadDataArr[0].length;
        
        var value:number = 0;
        var dx:number = 0;
        var dy:number = 0;

        for(var i:number = 0 ; i < len ; i++)
        {
            for(var j:number = 0 ; j < len2 ; j++)
            {
                value = mapData.roadDataArr[i][j];
                dx = j;
                dy = i;
                
                var node:RoadNode = MapRoadUtils.instance.getNodeByDerect(dx,dy);
                node.value = value;

                this._roadDic[node.cx + "_" + node.cy] = node;
            }
        }

        if(mapData.type == MapType.honeycomb)
        {
            this._roadSeeker = new AstarHoneycombRoadSeeker(this._roadDic)
        }else
        {
            this._roadSeeker = new AStarRoadSeeker(this._roadDic);
        }
        this.roadDrawManager.updateRoadDic(this._roadDic);
        this.node.width = this.mapLayer.width;
        this.node.height = this.mapLayer.height;
        this.setViewToPlayer();
    }

    public getMapNodeByPixel(px:number,py:number):RoadNode
    {
        var point:Point = MapRoadUtils.instance.getWorldPointByPixel(px,py);
        
        var node:RoadNode = this._roadDic[point.x + "_" + point.y];
        
        return node;
    }


    public onMapMouseDown(event:cc.Event.EventMouse):boolean
    {
        //var pos = this.node.convertToNodeSpaceAR(event.getLocation());
        // this.movePlayer(pos.x,pos.y);
        if(event.getButton() == cc.Event.EventMouse.BUTTON_RIGHT){
            var mapBg = this.mapLayer.node.getChildByName("MapBg");
            var pos = mapBg.convertToNodeSpaceAR(event.getLocation()); 
            var targetPoint:Point = MapRoadUtils.instance.getWorldPointByPixel(pos.x,pos.y);
            var targetNode:RoadNode = this._roadDic[targetPoint.x + "_" + targetPoint.y];
            if(this._mapState == MapState.addEnableRoad){
                targetNode.value = RoadState.walkNormal;
                this._mapData.roadDataArr[targetNode.dy][targetNode.dx] = RoadState.walkNormal;
            }else if(this._mapState == MapState.delRoad){
                targetNode.value = RoadState.unreache;
                this._mapData.roadDataArr[targetNode.dy][targetNode.dx] = RoadState.unreache;
            }else if(this._mapState >= MapState.shopRoad && this._mapState < MapState.startRoad){
                targetNode.value = this._mapState;
                this._mapData.roadDataArr[targetNode.dy][targetNode.dx] = this._mapState;
            }else if(this._mapState == MapState.startRoad){
                targetNode.value = RoadState.start;
                this._mapData.roadDataArr[targetNode.dy][targetNode.dx] = RoadState.start;
            }else if(this._mapState == MapState.endRoad){
                targetNode.value = RoadState.end;
                this._mapData.roadDataArr[targetNode.dy][targetNode.dx] = RoadState.end;
            }else if(this._mapState == MapState.eventRoad){
                targetNode.value = RoadState.event;
                this._mapData.roadDataArr[targetNode.dy][targetNode.dx] = RoadState.event;
            }
            this.roadDrawManager.updateRoadDic(this._roadDic);
            this._isRightMouse = true;
            let scrollView = this.mapLayer.getComponent(cc.ScrollView);
            scrollView.enabled = false;
        }
        return true;
    }

    public onMapMouseEnd(event:cc.Event.EventMouse):void{
        this._isRightMouse = false;
        let scrollView = this.mapLayer.getComponent(cc.ScrollView);
        scrollView.enabled = true;
    }
    
    public onMouseMove(event:cc.Event.EventMouse):void{
        if(this._isRightMouse == true){
            var mapBg = this.mapLayer.node.getChildByName("MapBg");
            var pos = mapBg.convertToNodeSpaceAR(event.getLocation()); 
            var targetPoint:Point = MapRoadUtils.instance.getWorldPointByPixel(pos.x,pos.y);
            var targetNode:RoadNode = this._roadDic[targetPoint.x + "_" + targetPoint.y];
            if(this._mapState == MapState.addEnableRoad){
                targetNode.value = RoadState.walkNormal;
                this._mapData.roadDataArr[targetNode.dy][targetNode.dx] = RoadState.walkNormal;
            }else if(this._mapState == MapState.delRoad){
                targetNode.value = RoadState.unreache;
                this._mapData.roadDataArr[targetNode.dy][targetNode.dx] = RoadState.unreache;
            }else if(this._mapState == MapState.addOptRoad){
                targetNode.value = RoadState.optWalk;
                this._mapData.roadDataArr[targetNode.dy][targetNode.dx] = RoadState.optWalk;
            }
            this.roadDrawManager.updateRoadDic(this._roadDic);
            this.roadDrawManager.updatePosInfo(pos);
        }
    }

    /**
     * 视图跟随玩家
     * @param dt 
     */
    public followPlayer(dt:number)
    {
        this.targetPos = this.player.node.position.sub(cc.v2(cc.winSize.width / 2,cc.winSize.height / 2));

        if(this.targetPos.x > this._mapData.mapWidth - cc.winSize.width)
        {
            this.targetPos.x = this._mapData.mapWidth - cc.winSize.width;
        }else if(this.targetPos.x < 0)
        {
            this.targetPos.x = 0;
            
        }    

        if(this.targetPos.y > this._mapData.mapHeight - cc.winSize.height)
        {
            this.targetPos.y = this._mapData.mapHeight - cc.winSize.height;
        }else if(this.targetPos.y < 0)
        {
            this.targetPos.y = 0;
        }
        

        //摄像机平滑跟随
        this.camera.node.position.lerp(this.targetPos,dt * 2.0,this.targetPos);
        this.camera.node.position = this.targetPos;
        
    }

    /**
        *移到玩家 
        * @param targetX 移动到的目标点x
        * @param targetY 移到到的目标点y
        * 
        */	
    public movePlayer(targetX:number,targetY:number)
    {
        var startPoint:Point = MapRoadUtils.instance.getWorldPointByPixel(this.player.node.x,this.player.node.y);
        var targetPoint:Point = MapRoadUtils.instance.getWorldPointByPixel(targetX,targetY);

        var startNode:RoadNode = this._roadDic[startPoint.x + "_" + startPoint.y];
        var targetNode:RoadNode = this._roadDic[targetPoint.x + "_" + targetPoint.y];

        var roadNodeArr:RoadNode[] = this._roadSeeker.seekPath(startNode,targetNode); //点击到障碍点不会行走
        //var roadNodeArr:RoadNode[] = this._roadSeeker.seekPath2(startNode,targetNode);  //点击到障碍点会行走到离障碍点最近的可走路点

        if(roadNodeArr.length > 0)
        {
            this.player.walkByRoad(roadNodeArr);
        }
    }


    /**
     *把视野定位到给定位置 
    * @param px
    * @param py
    * 
    */		
    public setViewToPoint(px:number,py:number):void
    {
        this.targetPos = cc.v2(px,py).sub(cc.v2(cc.winSize.width / 2,cc.winSize.height / 2));

        if(this.targetPos.x > this._mapData.mapWidth - cc.winSize.width)
        {
            this.targetPos.x = this._mapData.mapWidth - cc.winSize.width;
        }else if(this.targetPos.x < 0)
        {
            this.targetPos.x = 0;
        }    

        if(this.targetPos.y > this._mapData.mapHeight - cc.winSize.height)
        {
            this.targetPos.y = this._mapData.mapHeight - cc.winSize.height;
        }else if(this.targetPos.y < 0)
        {
            this.targetPos.y = 0;
        }
        
        this.camera.node.position = this.targetPos;
    }
    
    /**
     * 将视野对准玩家
     */
    public setViewToPlayer():void
    {
        this.setViewToPoint(this.player.node.x,this.player.node.y);
    }


    update (dt) 
    {
        if(this.isFollowPlayer)
        {
            this.followPlayer(dt);
            //this.camera.node.position = this.player.node.position.sub(cc.v2(cc.winSize.width / 2,cc.winSize.height / 2));
        }

    }

    //添加可走路径点
    onAddRunClick(){
        this._mapState = MapState.addEnableRoad;
        let scrollView = this.mapLayer.getComponent(cc.ScrollView);
        scrollView.enabled = false;
    }

    onDelRunClick(){
        this._mapState = MapState.delRoad;
        let scrollView = this.mapLayer.getComponent(cc.ScrollView);
        scrollView.enabled = false;
    }

    //添加透明路点
    onOptRunClick(){
        this._mapState = MapState.addOptRoad;
        let scrollView = this.mapLayer.getComponent(cc.ScrollView);
        scrollView.enabled = false;
    }
	
	//添加商店点
	onShopClick(sender:cc.Event.EventTouch){
        if(this._mapState >= MapState.shopRoad && this._mapState < MapState.startRoad){
            this._mapState += 1;
        }else{
		    this._mapState = MapState.shopRoad;
        }

        let button = sender.target;
        let label = cc.find("Background/Label",button).getComponent(cc.Label);
        label.string = "商店"+this._mapState;
		let scrollView = this.mapLayer.getComponent(cc.ScrollView);
        scrollView.enabled = false;
	}
		
	//添加起点
	onStartClick(){
		this._mapState = MapState.startRoad;
		let scrollView = this.mapLayer.getComponent(cc.ScrollView);
        scrollView.enabled = false;
	}
	
	//添加终点
	onEndClick(){
		this._mapState = MapState.endRoad;
		let scrollView = this.mapLayer.getComponent(cc.ScrollView);
        scrollView.enabled = false;
	}

    onEventClick(){
        this._mapState = MapState.eventRoad;
    }

    onNewMapClick(){
        this.newDialogNode.active = true;
        this.newDialogNode.getComponent("NewMapManager").setMapData(this._mapData);
    }

    onDownLoadClick(){
        this.downloadMapDataJson(this._mapData.name+".json",JSON.stringify(this._mapData));
    }

    downloadMapDataJson(filename, text) {
        var element = document.createElement('a');
        element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
        element.setAttribute('download', filename);
        element.style.display = 'none';
        document.body.appendChild(element);
        element.click();
        document.body.removeChild(element);
    }

    //打开新地图
    onOpenClick(){
        this.openDialogNode.active = true;
    }
	
}
